// Copyright (C) 1953-2024 NUDT
// Verilog module name - sync_transmitport_timestamp_record
// Version: V4.3.0.20240131
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//         
///////////////////////////////////////////////////////////////////////////
`timescale 1ns/1ps

module sync_transmitport_timestamp_record 
(
        i_clk,
        i_rst_n,
			
        //i_sync_step_mode,		
              
        iv_data,
        i_data_wr,
		o_data_ready,
		
        iv_local_counter,
		i_osm_sync_tx_pulse,
            
        ov_data,
        o_data_wr,
        i_data_ready		
);

// I/O
// clk & rst
input                  i_clk;                   //125Mhz
input                  i_rst_n;

//(*MARK_DEBUG="ture"*)input                  i_sync_step_mode;

(*MARK_DEBUG="ture"*)input      [8:0]       iv_data;
(*MARK_DEBUG="ture"*)input                  i_data_wr;

(*MARK_DEBUG="ture"*)input      [39:0]      iv_local_counter;
input		i_osm_sync_tx_pulse;

input		i_data_ready ;
output		o_data_ready ;

// send pkt    
(*MARK_DEBUG="ture"*)output reg [8:0]       ov_data;
(*MARK_DEBUG="ture"*)output reg             o_data_wr;

reg			r_osm_sync_tx_pulse; 
reg      [39:0]      rv_sync_tx_pit;//发送时间戳  
assign o_data_ready = i_data_ready;           
//***************************************************
//           record sync tx time
//***************************************************    
always @(posedge i_clk or negedge i_rst_n) begin
    if(!i_rst_n)begin
        rv_sync_tx_pit    <= 40'h0;

		r_osm_sync_tx_pulse<= 1'b0;
    end
    else begin
		r_osm_sync_tx_pulse<=i_osm_sync_tx_pulse;
		if ((r_osm_sync_tx_pulse==1'b0)&&(i_osm_sync_tx_pulse==1'b1))begin
			rv_sync_tx_pit<=iv_local_counter - {24'd16,16'b0};
		end
		else begin
			rv_sync_tx_pit<=rv_sync_tx_pit;
		end
	end
end 
//***************************************************
//            count cycles
//*************************************************** 
reg    [10:0]     rv_byte_cnt           ;   
always @(posedge i_clk or negedge i_rst_n) begin
    if(!i_rst_n)begin
        rv_byte_cnt    <= 11'h0;
    end
    else begin
		if (i_data_wr)begin
			//rv_byte_cnt <= rv_byte_cnt + 1'b1;
			rv_byte_cnt <= ((iv_data[8])&&(rv_byte_cnt>5))?11'h0:rv_byte_cnt + 1'b1;
		end
		else begin
			//rv_byte_cnt <= 11'b0;
			rv_byte_cnt <= rv_byte_cnt;
		end
	end
end                    
//***************************************************
//             transmit data 
//*************************************************** 
reg    [15:0]     rv_eth_type			;
reg    [7 :0]     rv_tsmp_type	        ;

reg    [39:0]     rv_used_sync_tx_pit   ;

(*MARK_DEBUG="ture"*)reg        [2:0]        rv_str_state;  
     
localparam              IDLE_S                      = 3'd0, 
                        EXTRACT_TYPE_S              = 3'd1,                       
						SEND_PIT_S                  = 3'd2,
                        TRANS_PKT_S                 = 3'd3;   
always @(posedge i_clk or negedge i_rst_n) begin
    if(i_rst_n == 1'b0)begin
        o_data_wr                   <= 1'b0;
        ov_data                     <= 9'h0; 

        rv_eth_type	               <= 16'b0;
        rv_tsmp_type	           <= 8'b0;
		
		rv_used_sync_tx_pit        <= 40'b0;
		
        rv_str_state          <= IDLE_S;
    end
    else begin
        case(rv_str_state)
            IDLE_S: begin
				if(i_data_wr && iv_data[8])begin//head
					o_data_wr    <= i_data_wr;
					ov_data      <= iv_data;

                    rv_str_state <= EXTRACT_TYPE_S;					
			    end
				else begin
					o_data_wr          <= 1'b0;
				    ov_data            <= 9'h0;
					rv_str_state <= IDLE_S;
				end
			end 

			EXTRACT_TYPE_S:begin
		        //if(i_data_wr)begin
					o_data_wr    <= i_data_wr;
					ov_data      <= iv_data;				
					if(rv_byte_cnt == 11'd12)begin
						rv_eth_type	               <= {iv_data[7:0],8'b0};				
					end	
					else if(rv_byte_cnt == 11'd13)begin
						rv_eth_type	               <= {rv_eth_type[15:8],iv_data[7:0]};				
					end
					else if(rv_byte_cnt == 11'd14)begin
						rv_tsmp_type	               <= iv_data[7:0];				
					end 
					else if(rv_byte_cnt == 11'd15)begin
						if((rv_eth_type == 16'hff01) && (rv_tsmp_type == 8'h06))begin
						    rv_str_state <= SEND_PIT_S;
                        end
                        else begin
                            rv_str_state <= TRANS_PKT_S;
                        end						
					end				
					else begin
						rv_str_state <= EXTRACT_TYPE_S;                    
					end
				//end
				//else begin
				//	o_data_wr    <= 1'b0;
				//	ov_data      <= 9'b0;	
				//	rv_str_state <= IDLE_S;
				//end
			end
			
            SEND_PIT_S:begin
                //if(i_data_wr)begin
				    o_data_wr    <= i_data_wr;
					
					if(rv_byte_cnt == 11'd23)begin
						ov_data      <= iv_data;
                        rv_used_sync_tx_pit <= rv_sync_tx_pit;					
					end					
					else if(rv_byte_cnt == 11'd24)begin
						ov_data      <= {1'b0,rv_used_sync_tx_pit[39:32]};	
					end
					else if(rv_byte_cnt == 11'd25)begin
						ov_data      <= {1'b0,rv_used_sync_tx_pit[31:24]};	
					end
					else if(rv_byte_cnt == 11'd26)begin
						ov_data      <= {1'b0,rv_used_sync_tx_pit[23:16]};	
					end
					else if(rv_byte_cnt == 11'd27)begin
						ov_data      <= {1'b0,rv_used_sync_tx_pit[15:8]};	
					end
					else if(rv_byte_cnt == 11'd28)begin
						ov_data      <= {1'b0,rv_used_sync_tx_pit[7:0]};	
						rv_str_state <= TRANS_PKT_S;
					end					
					else begin
						ov_data      <= iv_data;
					end		
			    //end
                //else begin
				//	o_data_wr    <= 1'b0;
				//	ov_data      <= 9'b0;	
				//	rv_str_state <= IDLE_S;
                //end
            end
			TRANS_PKT_S:begin                        
				//if(i_data_wr)begin
				    o_data_wr    <= i_data_wr;
					ov_data      <= iv_data;
                    if(iv_data[8])begin//tail						
					    rv_str_state <= IDLE_S;
				    end
					else begin
					    rv_str_state <= TRANS_PKT_S;
					end
				//end
				//else begin
				//	o_data_wr    <= 1'b0;
				//	ov_data      <= 9'b0;	
				//	rv_str_state <= IDLE_S;
				//end
			end
            default:begin
                rv_str_state            <= IDLE_S;
            end
        endcase
    end
end
endmodule 